package edu.unice.simul.vue.moteur_graphique;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;

import javax.swing.JPanel;
import javax.swing.border.LineBorder;

import edu.unice.simul.conf.GeneralSettings;
import edu.unice.simul.modele.contenus.Contenu;
import edu.unice.simul.modele.contenus.immobiles.Mur;
import edu.unice.simul.modele.contenus.immobiles.Sortie;
import edu.unice.simul.modele.contenus.mobiles.Humain;
import edu.unice.simul.util.Dim;

/**
 * Moteur graphique de la simulation
 * 
 * @author Romain Ciaccafava
 * 
 */
public class MoteurGraphique extends JPanel {
	private static final long serialVersionUID = 5238144421240552596L;
	private List<Humain> mobiles = null;
	private List<Contenu> contenu;
	private int size = GeneralSettings.TAILLE_CASE;
	/**
	 * Valeur par défaut pour l'affichage de la vision des humains
	 */
	private boolean vision = true;
	/**
	 * Valeur par défaut pour l'affichage de la direction des humains
	 */
	private boolean direction = true;
	/**
	 * Valeur par défaut pour l'affichage du niveau de vie des humains
	 */
	private boolean vie = false;

	public MoteurGraphique(List<Contenu> contenu, Dim dimPiece) {
		this.contenu = contenu;
		setBackground(Color.WHITE);
		setBorder(new LineBorder(Color.BLACK));
		setSize(new Dimension(dimPiece.getX() * size, dimPiece.getY() * size));
		setPreferredSize(new Dimension(dimPiece.getX() * size, dimPiece.getY()
				* size));
	}

	public void refresh(List<Humain> mobiles) {
		this.mobiles = mobiles;
		repaint();
	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);

		Composite composite = ((Graphics2D) g).getComposite();

		for (Contenu c : this.contenu)
			if (c instanceof Mur) {
				g.setColor(Color.BLACK);
				g.fillRect(c.getPosition().getX() * size,
						c.getPosition().getY() * size, size, size);
			}

		for (Contenu c : this.contenu)
			if (c instanceof Sortie) {
				g.setColor(Color.RED);
				g.fillRect(c.getPosition().getX() * size,
						c.getPosition().getY() * size, size, size);
			}

		if (this.mobiles != null) {
			for (Humain m : this.mobiles) {
				if (m instanceof Humain && !((Humain) m).estSorti()) {
					g.setColor(Color.BLUE);
					g.fillOval(m.getPosition().getX() * size, m.getPosition().getY()
							* size, size, size);
					g.setColor(Color.RED);

					Humain h = (Humain) m;

					// Direction
					if (direction)
						g.drawLine(
								m.getPosition().getX() * size + size / 2,
								m.getPosition().getY() * size + size / 2,
								(int) ((m.getPosition().getX() + (2 * Math.cos(m.getDirection()
										.getDirection()))) * size + size / 2),
								(int) ((m.getPosition().getY() + (2 * Math.sin(m.getDirection()
										.getDirection()))) * size + size / 2));

					if (vision) {

						double vision1X = (h.getDistanceVision()
								* Math.cos(h.getAngleVision() / 2
										+ h.getDirection().getDirection()) + h.getPosition().getX())
								* size;
						double vision1Y = (h.getDistanceVision()
								* Math.sin(h.getAngleVision() / 2
										+ h.getDirection().getDirection()) + h.getPosition().getY())
								* size;

						double vision2X = (h.getDistanceVision()
								* Math.cos(-h.getAngleVision() / 2
										+ h.getDirection().getDirection()) + h.getPosition().getX())
								* size;
						double vision2Y = (h.getDistanceVision()
								* Math.sin(-h.getAngleVision() / 2
										+ h.getDirection().getDirection()) + h.getPosition().getY())
								* size;

						int[] x = { (int) vision1X + size / 2, (int) vision2X + size / 2,
								h.getPosition().getX() * size + size / 2 };
						int[] y = { (int) vision1Y + size / 2, (int) vision2Y + size / 2,
								h.getPosition().getY() * size + size / 2 };

						g.setColor(Color.GREEN);
						((Graphics2D) g).setComposite(AlphaComposite.getInstance(
								AlphaComposite.SRC_OVER, 0.3f));
						g.fillPolygon(x, y, 3);
					}

					((Graphics2D) g).setComposite(composite);

					if (vie) {
						int widthBox = 20, heightBox = 5;
						g.setColor(Color.BLACK);
						g.drawRect(h.getPosition().getX() * size - widthBox / 2 + size / 2,
								h.getPosition().getY() * size - heightBox * 2, widthBox,
								heightBox);

						if (h.getPrcVie() > 75)
							g.setColor(Color.GREEN);
						else if (h.getPrcVie() > 25)
							g.setColor(Color.ORANGE);
						else
							g.setColor(Color.RED);

						g.fillRect(h.getPosition().getX() * size - widthBox / 2 + size / 2
								+ 1, h.getPosition().getY() * size - heightBox * 2 + 1,
								(int) ((widthBox - 1) * (h.getPrcVie() / 100)), heightBox - 1);
					}
				}
			}
		} else
			for (Contenu c : this.contenu) {
				if (c instanceof Humain && !((Humain) c).estSorti()) {
					g.setColor(Color.BLUE);
					g.fillOval(c.getPosition().getX() * size, c.getPosition().getY()
							* size, size, size);
				}
			}
	}

	public void afficherDirection(boolean value) {
		this.direction = value;
	}

	public void afficherVision(boolean value) {
		this.vision = value;
	}

	public void afficherVie(boolean value) {
		this.vie = value;
	}
}
